﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CRMWeb.Pages.Test
{
    public partial class TestCompoundIntrestCalculator : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button3_Click(object sender, EventArgs e)
        {

            //New Code
            double noofdays = double.Parse(txtNumberofDays.Text);
            decimal principal = decimal.Parse(txtPrincipal.Text);
            int loanduration = int.Parse(txtLoanDuration.Text);
            decimal interestrate = decimal.Parse(txtInterestRate.Text);
            DateTime nextrepaymentdate = DateTime.Parse(txtFirstRepaymentDate.Text);
            DateTime lastrepaymentdate = DateTime.Parse(txtLastRepaymentDate.Text);
            int numberofinstallments = int.Parse(txtNoofInstallments.Text);
            decimal repayment = decimal.Parse(txtRepayment.Text);
            int daysinyear = int.Parse(txtDaysinayear.Text);
            DateTime duedate = DateTime.Parse(txtLoanDate.Text);
            DateTime prevduedate;
            decimal interest, daydiff, totalinterest = 0, cntinterest = 0, prevprincipal, finalinterest = 0, totalintrest1 = 0, PVofEMI = 0;

            //declaration of discount factor
            decimal trialrateforcopmpintrat = (((((interestrate / 100) * decimal.Parse(noofdays.ToString())) / 265) / 2) * 100);

            DataTable dtSchedule = new DataTable();
            dtSchedule.Columns.Add("Next Interest Date", typeof(DateTime));
            dtSchedule.Columns.Add("Next Repayment Date", typeof(DateTime));
            dtSchedule.Columns.Add("Pay", typeof(string));
            dtSchedule.Columns.Add("Due Date", typeof(DateTime));
            dtSchedule.Columns.Add("Repayment", typeof(decimal));
            dtSchedule.Columns.Add("Interest Total", typeof(decimal));
            dtSchedule.Columns.Add("Balance", typeof(decimal));
            dtSchedule.Columns.Add("Interest", typeof(decimal));
            dtSchedule.Columns.Add("Disc Factor", typeof(decimal));
            DataRow dr = dtSchedule.NewRow();
            DateTime nextintrestdate = (duedate.AddMonths(1).AddDays(1 - duedate.Day).Date).AddDays(-1);
            int quarter = (int)Math.Ceiling(duedate.Month / 3.0);
            int lastMonthInQuarter = 3 * quarter;
            DateTime nextintrestdate1 = new DateTime(duedate.Year, lastMonthInQuarter, DateTime.DaysInMonth(duedate.Year, lastMonthInQuarter));
            dr["Next Interest Date"] = nextintrestdate1;
            dr["Next Repayment Date"] = nextrepaymentdate;
            dr["Pay"] = "advance";
            dr["Due Date"] = duedate;
            dr["Interest Total"] = principal;
            dr["Balance"] = principal;
            dr["Disc Factor"] = 0.00;
            dtSchedule.Rows.Add(dr);

            for (int cnt = 0; cnt < numberofinstallments; cnt++)
            {
                if (nextintrestdate < nextrepaymentdate)
                {
                    prevduedate = duedate;
                    duedate = nextintrestdate;

                    //interest calculation
                    interest = Math.Round(decimal.Parse((((duedate - prevduedate).TotalDays + 1) / daysinyear).ToString()) * (interestrate / 100) * principal, 2);

                    //total interest calculation
                    if (cnt == 0)
                        totalinterest = interest;
                    else
                        totalinterest = cntinterest + interest;

                    DataRow dr1 = dtSchedule.NewRow();
                    nextintrestdate = (nextrepaymentdate.AddMonths(1).AddDays(1 - nextrepaymentdate.Day).Date).AddDays(-1);
                    dr1["Next Interest Date"] = nextintrestdate;
                    dr1["Next Repayment Date"] = nextrepaymentdate;
                    dr1["Pay"] = "interest";
                    dr1["Due Date"] = duedate;
                    dr1["Repayment"] = 0.00;
                    dr1["Interest Total"] = totalinterest;
                    principal = principal + totalinterest;
                    dr1["Balance"] = principal;
                    dr1["Interest"] = interest;
                    totalintrest1 = totalintrest1 + interest;
                    dr1["Disc Factor"] = 0.00;
                    dtSchedule.Rows.Add(dr1);
                    cntinterest = 0;
                }

                prevduedate = duedate;
                duedate = nextrepaymentdate;
                if ((nextintrestdate1 - nextrepaymentdate).TotalDays < 30 || cnt != 0)
                    nextrepaymentdate = nextrepaymentdate.AddDays(noofdays);

                //interest calculation
                if (cntinterest == 0)
                    daydiff = decimal.Parse((((duedate - prevduedate).TotalDays - 1) / daysinyear).ToString());
                else
                    daydiff = decimal.Parse(((duedate - prevduedate).TotalDays / daysinyear).ToString());
                interest = Math.Round(daydiff * (interestrate / 100) * principal, 2);
                cntinterest += interest;

                DataRow dr2 = dtSchedule.NewRow();
                dr2["Next Interest Date"] = nextintrestdate;
                dr2["Next Repayment Date"] = nextrepaymentdate;
                dr2["Pay"] = (cnt + 1).ToString();
                dr2["Due Date"] = duedate;
                prevprincipal = principal;
                principal = principal - repayment;
                if (prevprincipal < repayment)
                {
                    dr2["Interest Total"] = interest;
                    dr2["Repayment"] = prevprincipal + interest;
                    finalinterest = prevprincipal + interest;
                    dr2["Balance"] = 0.00;
                }
                else
                {
                    dr2["Interest Total"] = 0.00;
                    dr2["Repayment"] = repayment;
                    dr2["Balance"] = principal;
                }
                dr2["Interest"] = interest;
                totalintrest1 = totalintrest1 + interest;

                //calculation of discount factor
                //lblTrialrateforCompIntt.Text = Math.Round(Calc_int(interestrate, noofdays), 2).ToString();
                dr2["Disc Factor"] = Math.Round(Math.Pow((1 / (1 + (double.Parse(lblTrialrateforCompIntt.Text) / 100))), (cnt + 2)), 2);
                PVofEMI += repayment * decimal.Parse(Math.Round(Math.Pow((1 / (1 + (double.Parse(lblTrialrateforCompIntt.Text) / 100))), (cnt + 2)), 2).ToString());
                dtSchedule.Rows.Add(dr2);

                if (prevprincipal < repayment)
                    break;
            }

            dvSchedule.DataSource = dtSchedule;
            dvSchedule.DataBind();

            //calculation of others
            lblPreEMIInterest.Text = Math.Round(decimal.Parse(dtSchedule.Rows[1].ItemArray[7].ToString()), 0).ToString();
            double rate = double.Parse(((interestrate / 100) / numberofinstallments).ToString());
            int nper = numberofinstallments;
            double pv = double.Parse((-Math.Round(decimal.Parse(dtSchedule.Rows[1].ItemArray[7].ToString()), 0) - decimal.Parse(txtPrincipal.Text)).ToString());
            double pmt = Pmt(rate, nper, pv);
            lblTotalIntrest.Text = totalintrest1.ToString();
            lblInitialInstallment.Text = Math.Round(pmt, 2).ToString();
            lblEMILastInstallment.Text = (repayment - finalinterest).ToString();
            lblPVofEMIs.Text = Math.Round(PVofEMI, 2).ToString();
            lblDifference.Text = (Math.Round((PVofEMI - decimal.Parse(txtPrincipal.Text)), 2)).ToString();
            if (noofdays == 7)
            {
                lblComparisonRate.Text = (Math.Round((double.Parse(lblTrialrateforCompIntt.Text) * 52.18), 2)).ToString();
                lblRevisedRepayment.Text = (((Math.Round(Pmt((double.Parse(lblComparisonRate.Text) / 52.18), numberofinstallments, -double.Parse(txtPrincipal.Text)), 2) + 0.02) * (double.Parse(interestrate.ToString()) / 100)) / 0.48).ToString();
            }
            if (noofdays == 30)
            {
                lblComparisonRate.Text = (Math.Round((double.Parse(lblTrialrateforCompIntt.Text) * 12), 2)).ToString();
                lblRevisedRepayment.Text = (((Math.Round(Pmt((double.Parse(lblComparisonRate.Text) / 12), numberofinstallments, -double.Parse(txtPrincipal.Text)), 2) + 0.02) * (double.Parse(interestrate.ToString()) / 100)) / 0.48).ToString();
            }
            if (noofdays == 14)
            {
                lblComparisonRate.Text = (Math.Round((double.Parse(lblTrialrateforCompIntt.Text) * 26.09), 2)).ToString();
                lblRevisedRepayment.Text = (((Math.Round(Pmt((double.Parse(lblComparisonRate.Text) / 26.09), numberofinstallments, -double.Parse(txtPrincipal.Text)), 2) + 0.02) * (double.Parse(interestrate.ToString()) / 100)) / 0.48).ToString();
            }

        }

        public double Pmt(double rate, int numberOfPayments, double amount)
        {
            double temp = System.Math.Pow((rate + 1), numberOfPayments);
            return ((-amount * temp) / ((temp - 1)) * rate);
        }

        //public double Sumproduct()
        //{
        //    double temp = 0;
        //    int[] a1 = { 2, 3, 4 };
        //    int[] a2 = { 5, 10, 20 };
        //    for (int i = 0; i < 3; i++)
        //    {
        //        temp += a1[i] * a2[i];
        //    }
        //    return temp;
        //}

        public decimal Calc_int(decimal interestrate, double noofdays)
        {
            decimal INTT = 0;
            double q21 = double.Parse(lblDifference.Text), x;
            int i = 0;
            decimal trialrateforcopmpintrat = ((((interestrate) * decimal.Parse(noofdays.ToString())) / 365) / 2);
            x = 0.01;
            if (q21 != 0.00)
            {
                while (x > 0.0000000005)
                {
                    while (q21 > 0.0001)
                    {
                        if (i > 40)
                            break;

                        INTT = trialrateforcopmpintrat + decimal.Parse(x.ToString());
                        if (x.ToString() != null)
                            trialrateforcopmpintrat = Math.Round(INTT, 2);
                        i = i + 1;
                    }
                    if (x.ToString() != null)
                        trialrateforcopmpintrat = Math.Round(INTT, 2) - decimal.Parse(x.ToString());
                    x = x / 10;
                }
            }
            return trialrateforcopmpintrat;
        }
    }
}